<template>
  <div 
    class="monaco-editor-container" 
    :style="{ height: props.height ? height + 'px' : (codeLines * 20) + 'px' }"
  >
    <div ref="editorContainer" class="editor-container"></div>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, watch, nextTick } from 'vue';

// 导入Monaco Editor核心和语言支持
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';

// 导入语言支持
import 'monaco-editor/esm/vs/basic-languages/javascript/javascript.contribution';

// 导入语言服务支持 - 这些是实现语法校验的关键模块
import 'monaco-editor/esm/vs/language/typescript/monaco.contribution';
import 'monaco-editor/esm/vs/language/json/monaco.contribution';
import 'monaco-editor/esm/vs/language/css/monaco.contribution';
import 'monaco-editor/esm/vs/language/html/monaco.contribution';

// 初始化Monaco编辑器的URI处理
self.MonacoEnvironment = {
  getWorkerUrl: function (moduleId, label) {
    // 注意：这些路径可能需要根据您的项目设置进行调整
    if (label === 'javascript' || label === 'typescript') {
      return '/monaco-editor/vs/language/typescript/ts.worker.js';
    }
    if (label === 'json') {
      return '/monaco-editor/vs/language/json/json.worker.js';
    }
    if (label === 'css' || label === 'scss' || label === 'less') {
      return '/monaco-editor/vs/language/css/css.worker.js';
    }
    if (label === 'html' || label === 'handlebars' || label === 'razor') {
      return '/monaco-editor/vs/language/html/html.worker.js';
    }
    return '/monaco-editor/vs/editor/editor.worker.js';
  }
};

// 不再单独导入编辑器功能，这些已包含在editor.api.js中

/**
 * @description: Monaco Editor 组件
 * @author: Your Name
 */

// 定义组件属性
const props = defineProps({
  /**
   * 编辑器初始值
   */
  modelValue: {
    type: String,
    default: ''
  },
  /**
   * 编辑器语言
   * @values javascript, typescript, html, css, json, sql, xml, markdown, etc.
   */
  language: {
    type: String,
    default: 'javascript'
  },
  /**
   * 编辑器主题
   * @values vs, vs-dark, hc-black
   */
  theme: {
    type: String,
    default: 'vs-dark'
  },
  /**
   * 编辑器高度
   */
  height: {
    type: Number,
    default: 0
  },
  /**
   * 是否只读
   */
  readOnly: {
    type: Boolean,
    default: false
  },
  /**
   * 自动完成选项
   */
  autoComplete: {
    type: Boolean,
    default: true
  },
  /**
   * 是否显示行号
   */
  lineNumbers: {
    type: Boolean,
    default: true
  },
  /**
   * 是否显示缩进参考线
   */
  renderIndentGuides: {
    type: Boolean,
    default: true
  },
  /**
   * 是否折叠代码
   */
  folding: {
    type: Boolean,
    default: true
  },
  /**
   * 是否启用语法错误校验
   */
  lintCheck: {
    type: Boolean,
    default: true
  },
  /**
   * 错误标记的延迟时间(ms)
   */
  lintDelay: {
    type: Number,
    default: 500
  },
  /**
   * 自定义编辑器配置
   */
  options: {
    type: Object,
    default: () => ({})
  }
});

// 定义事件
const emit = defineEmits(['update:modelValue', 'change', 'editorDidMount', 'lintError']);

// 引用编辑器容器
const editorContainer = ref(null);
// 编辑器实例
let editor = null;
// 编辑器模型
let editorModel = null;
// 记录编辑器是否已初始化
const isEditorInitialized = ref(false);
// 记录是否需要重新聚焦
const needRefocus = ref(false);

function countNewlines(str) {
  // 匹配换行符 \n
  const matches = str.match(/\n/g)
  return matches ? matches.length : 0
}

const codeLines = ref(8)
// 监听内容变化并获取行数
watch(() => props.modelValue, () => {
  const count = countNewlines(props.modelValue) + 1
  if(8 < count) {
    codeLines.value = count
  } else {
    codeLines.value = 8
  }
}, { immediate: true })

// const getCodeLines = 

/**
 * 初始化编辑器
 */
const initMonaco = () => {
  if (!editorContainer.value) return;
  
  // 设置编辑器主题
  monaco.editor.defineTheme('vs-dark-enhanced', {
    base: 'vs-dark',
    inherit: true,
    rules: [
      { token: 'comment', foreground: '6A9955' },
      { token: 'keyword', foreground: '569CD6', fontStyle: 'bold' },
      { token: 'string', foreground: 'CE9178' },
      { token: 'number', foreground: 'B5CEA8' },
      { token: 'regexp', foreground: 'D16969' },
      { token: 'operator', foreground: 'D4D4D4' },
      { token: 'function', foreground: 'DCDCAA' },
      { token: 'variable', foreground: '9CDCFE' },
      { token: 'type', foreground: '4EC9B0' },
      { token: 'class', foreground: '4EC9B0', fontStyle: 'bold' }
    ],
    colors: {
      'editor.background': '#1E1E1E',
      'editor.foreground': '#D4D4D4',
      'editorLineNumber.foreground': '#858585',
      'editorCursor.foreground': '#AEAFAD',
      'editor.selectionBackground': '#264F78',
      'editor.inactiveSelectionBackground': '#3A3D41',
      'editorWhitespace.foreground': '#3B3B3B'
    }
  });
  
  // 合并用户配置和默认配置
  const editorOptions = {
    value: props.modelValue,
    language: props.language,
    theme: 'vs-dark-enhanced', // 使用增强的主题
    readOnly: props.readOnly,
    lineNumbers: props.lineNumbers ? 'on' : 'off',
    renderIndentGuides: props.renderIndentGuides,
    folding: props.folding,
    automaticLayout: true,
    scrollBeyondLastLine: false,
    minimap: {
      enabled: true
    },
    contextmenu: true,
    fixedOverflowWidgets: true,
    // 确保编辑器可编辑
    domReadOnly: false,
    // 增强语法高亮设置
    tokenization: {
      maxTokenizationLineLength: 5000
    },
    // 语法高亮配置
    'semanticHighlighting.enabled': true,
    // 启用代码检查
    'editor.quickSuggestions': {
      other: true,
      comments: false,
      strings: false
    },
    'editor.parameterHints.enabled': true,
    'editor.suggestOnTriggerCharacters': true,
    'editor.acceptSuggestionOnEnter': 'on',
    'editor.snippetSuggestions': 'top',
    ...props.options
  };

  try {
    // 创建编辑器实例
    editor = monaco.editor.create(editorContainer.value, editorOptions);
  
    // 创建模型，确保模型有效
    editorModel = editor.getModel();
  
    // 如果模型不存在，创建一个新模型
    if (!editorModel) {
      // 使用随机生成的URI以避免冲突
      const uri = monaco.Uri.parse(`file:///main-${Date.now()}.${props.language}`);
      editorModel = monaco.editor.createModel(props.modelValue, props.language, uri);
      editor.setModel(editorModel);
    }
  
    // 配置语法验证
    if (props.language === 'javascript') {
      monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
        noSemanticValidation: !props.lintCheck,
        noSyntaxValidation: !props.lintCheck,
        diagnosticCodesToIgnore: []
      });
      
      // 设置JavaScript编译器选项
      monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
        target: monaco.languages.typescript.ScriptTarget.ES2020,
        allowNonTsExtensions: true,
        moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
        module: monaco.languages.typescript.ModuleKind.CommonJS,
        noEmit: true,
        esModuleInterop: true,
        jsx: monaco.languages.typescript.JsxEmit.React,
        allowJs: true,
        typeRoots: ["node_modules/@types"]
      });
    }
  
    // 配置JSON验证
    if (props.language === 'json') {
      monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
        validate: props.lintCheck,
        allowComments: true,
        schemas: [],
        enableSchemaRequest: true
      });
    }
    
    // 监听内容变化
    editor.onDidChangeModelContent(() => {
      const value = editor.getValue();
      emit('update:modelValue', value);
      emit('change', value);
      
      // 如果启用了语法检查，延迟执行以避免频繁检查
      if (props.lintCheck) {
        debouncedLintCheck();
      }
    });
    
    // 监听焦点变化
    editor.onDidBlurEditorWidget(() => {
      // 仅记录焦点状态，不主动尝试重新获取焦点
      needRefocus.value = true;
    });
    
    // 监听键盘输入
    editor.onKeyDown((e) => {
      // 确保编辑器处于活动状态
      if (needRefocus.value) {
        editor.focus();
        needRefocus.value = false;
      }
    });
    
    // 触发编辑器挂载完成事件
    emit('editorDidMount', editor);
    isEditorInitialized.value = true;
    
    // 确保编辑器获得焦点
    setTimeout(() => {
      // 默认不给它焦点 ***
      // editor.focus();
    }, 100);
  } catch (error) {
    console.error('Monaco Editor初始化失败:', error);
  }
};

/**
 * 执行语法检查
 */
const performLintCheck = () => {
  if (!editor || !editorModel) return;
  
  // 安全地获取当前编辑器的所有标记
  let markers = [];
  try {
    if (editorModel && editorModel.uri) {
      markers = monaco.editor.getModelMarkers({ resource: editorModel.uri });
    } else {
      markers = monaco.editor.getModelMarkers();
    }
  } catch (error) {
    console.error('Error getting model markers:', error);
    markers = [];
  }
  
  // 过滤出错误和警告
  const errors = markers.filter(marker => 
    marker.severity === monaco.MarkerSeverity.Error || 
    marker.severity === monaco.MarkerSeverity.Warning
  );
  
  // 发送错误信息
  emit('lintError', errors);
  
  return errors;
};

// 创建一个防抖函数来执行语法检查
const debouncedLintCheck = (() => {
  let timeout = null;
  return () => {
    clearTimeout(timeout);
    timeout = setTimeout(() => {
      performLintCheck();
    }, props.lintDelay);
  };
})();

/**
 * 销毁编辑器
 */
const disposeMonaco = () => {
  if (editor) {
    editor.dispose();
    editor = null;
  }
};

/**
 * 设置编辑器值
 */
const setValue = (value) => {
  if (editor) {
    editor.setValue(value);
  }
};

/**
 * 格式化代码
 */
const formatCode = () => {
  if (editor) {
    editor.getAction('editor.action.formatDocument').run();
  }
};

// 监听 modelValue 变化
watch(() => props.modelValue, (newValue) => {
  if (editor && newValue !== editor.getValue()) {
    editor.setValue(newValue);
  }
});

// 监听 language 变化
watch(() => props.language, (newValue) => {
  if (editor && editorModel) {
    monaco.editor.setModelLanguage(editorModel, newValue);
    
    // 语言变化后重新检查语法
    if (props.lintCheck) {
      setTimeout(() => {
        performLintCheck();
      }, props.lintDelay);
    }
  }
});

// 监听 theme 变化
watch(() => props.theme, (newValue) => {
  if (editor) {
    monaco.editor.setTheme(newValue);
  }
});

// 监听 readOnly 变化
watch(() => props.readOnly, (newValue) => {
  if (editor) {
    editor.updateOptions({ readOnly: newValue });
  }
});

// 移除容器点击事件处理函数

// 不再使用mousedown事件，避免被动事件监听器问题

// 组件挂载时初始化编辑器
onMounted(() => {
  // 使用nextTick确保DOM已完全渲染
  nextTick(() => {
    try {
      initMonaco();
      
      // 添加容器点击事件监听，使用原生方式避免被动监听器问题
      if (editorContainer.value) {
        editorContainer.value.addEventListener('click', () => {
          if (editor && isEditorInitialized.value) {
            editor.focus();
          }
        }, { passive: true });
      }
    } catch (error) {
      console.error('Error initializing Monaco Editor:', error);
    }
  });
});

// 组件卸载前销毁编辑器
onBeforeUnmount(() => {
  disposeMonaco();
});

// 暴露方法
defineExpose({
  editor: () => editor,
  monaco,
  formatCode,
  setValue,
  performLintCheck
});
</script>

<style scoped>
.monaco-editor-container {
  width: 100%;
  border: 1px dashed #ccc;
  position: relative;
  text-align: left;
  overflow: hidden;
  /* 确保容器可以接收事件 */
  cursor: text;
  z-index: 1;
  /* 完全禁用触摸事件的默认行为 */
  touch-action: none;
}

.editor-container {
  width: 100%;
  height: 100%;
  /* 确保编辑器容器可以接收输入 */
  pointer-events: auto;
}

/* 确保编辑器内容区域可编辑 */
:deep(.monaco-editor) {
  pointer-events: auto !important;
}

:deep(.monaco-editor-background) {
  pointer-events: auto !important;
}

:deep(.monaco-editor .overflow-guard) {
  pointer-events: auto !important;
}

:deep(.monaco-editor .cursor) {
  /* 增强光标可见度 */
  border-left-width: 2px !important;
  border-left-color: #AEAFAD !important;
}

/* 确保编辑器内容区域始终可以接收事件 */
:deep(.monaco-editor .view-lines) {
  pointer-events: auto !important;
  user-select: text !important;
}
</style>
